package com.jing.ads.downloader;

import java.io.File;
import java.util.HashSet;
import java.util.Iterator;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.jing.ads.R;
import com.jing.ads.application.GlobalConstants;
import com.jing.ads.handler.LogHandler;
import com.jing.ads.net.RequestListener;
import com.jing.ads.util.GlobalUtil;
import com.jing.ads.util.SQLUtil;
import com.jing.ads.util.StringUtil;

public class DownloadManager {

	private static DownloadManager sInstance;
	private final Context mContext;

	private DownloadManager(Context context) {
		mContext = context;
	}

	public synchronized static DownloadManager getInstance(Context context) {
		if (sInstance == null) {
			sInstance = new DownloadManager(context);
		}
		return sInstance;
	}

	public void startDownload(final String downloadUrl, final int appId,
			final String packageName, final String title, final long size) {
		if (TextUtils.isEmpty(downloadUrl) || appId < 0) {
			 throw new IllegalArgumentException();
			// GlobalUtil.shortToast(mContext, R.string.downlod_error_msg);
//			return;
		}

		if (!Helpers.checkSpaceEnough(mContext, size)) {
			// Intent intent = new Intent(mContext,
			// ActivityWarningDownload.class);
			// mContext.startActivity(intent);

			return;
		}
		
		sendLog(packageName, LogHandler.ACTION_DOWNLOAD);
		
		ContentResolver contentResolver = mContext.getContentResolver();

		int downloadId = -1;
		int downloadStatus = -1;
		String notifyPkgName = null;
		String notifyClass = null;
		String notifyExtras = null;
		String filePath = null;

		Uri uri = null;
		Cursor cursor = null;
		if (downloadUrl != null && !StringUtil.isEmpty(downloadUrl)
				&& appId >= 0) {
			cursor = contentResolver.query(
					Downloads.CONTENT_URI,
					new String[] { Downloads._ID, 
							Downloads.COLUMN_STATUS,
							Downloads.COLUMN_NOTIFICATION_PACKAGE,
							Downloads.COLUMN_NOTIFICATION_CLASS,
							Downloads.COLUMN_NOTIFICATION_EXTRAS,
							Downloads._DATA },
					SQLUtil.getSelectionAnd(new String[] {
							Downloads.COLUMN_APP_ID, Downloads.COLUMN_URI }),
					new String[] { String.valueOf(appId), downloadUrl }, null);
		}

		if (cursor != null && cursor.moveToFirst()) {
			downloadId = cursor.getInt(0);
			downloadStatus = cursor.getInt(1);
			notifyPkgName = cursor.getString(2);
			notifyClass = cursor.getString(3);
			notifyExtras = cursor.getString(4);
			filePath = cursor.getString(5);

			cursor.close();
		}

//		Log.d("DownloadManager_", "appId: " + appId);
//		Log.d("DownloadManager_", "downloadUrl: " + downloadUrl);
//		Log.d("DownloadManager_", "cursor: " + cursor);
//		Log.d("DownloadManager_", "downloadId: " + downloadId);
//		Log.d("DownloadManager_", "downloadStatus: " + downloadStatus);
//		Log.d("DownloadManager_", "notifyPkgName: " + notifyPkgName);
//		Log.d("DownloadManager_", "notifyClass: " + notifyClass);
//		Log.d("DownloadManager_", "notifyExtras: " + notifyExtras);
//		Log.d("DownloadManager_", "filePath: " + filePath);

		if (downloadId > 0) {
			uri = Uri.parse(Downloads.CONTENT_URI + "/" + downloadId);
		}

		if (downloadStatus == -1) {
			uri = insertDownloadUri(contentResolver, downloadUrl, appId, title,
					packageName);
			if (uri == null) {
				 throw new NullPointerException("downloadUri is null");
//				GlobalUtil.shortToast(mContext, R.string.downlod_error_msg);
//				return;
			}
		} else if (downloadStatus == Downloads.STATUS_SUCCESS) {// 下载已完�?
			if (new File(filePath).exists()) {
//				Intent intent = new Intent(Downloads.DOWNLOAD_COMPLETED_ACTION);
////				intent.setClassName(notifyPkgName, notifyClass);
//				if (notifyExtras != null) {
//					intent.putExtra(Downloads.COLUMN_NOTIFICATION_EXTRAS,
//							notifyExtras);
//				}
//				intent.setData(uri);
//				mContext.sendBroadcast(intent);
				System.out.println("successed");
				return;
			} else {
				contentResolver.delete(uri, null, null);

				uri = insertDownloadUri(contentResolver, downloadUrl, appId,
						title, packageName);
				if (uri == null) {
					 throw new NullPointerException("downloadUri is null");
//					GlobalUtil.shortToast(mContext, R.string.downlod_error_msg);
//					return;
				}
			}
		} else if (Downloads.isStatusError(downloadStatus)) {// 下载错误，删除上次下载地�?��采用�?��下载地址
			contentResolver.delete(uri, null, null);

			uri = insertDownloadUri(contentResolver, downloadUrl, appId, title,
					packageName);
			if (uri == null) {
				 throw new NullPointerException("downloadUri is null");
//				GlobalUtil.shortToast(mContext, R.string.downlod_error_msg);
//				return;
			}
		} else if (downloadStatus == Downloads.STATUS_RUNNING
				|| downloadStatus == Downloads.STATUS_PENDING) {
//			GlobalUtil.shortToast(mContext, R.string.download_started_msg);
			return;
		} else {
			if (uri != null) {
				ContentValues values = new ContentValues();
				values.put(Downloads.COLUMN_VISIBILITY,
						Downloads.VISIBILITY_VISIBLE);
				values.put(Downloads.COLUMN_CONTROL, Downloads.CONTROL_RUN);
				contentResolver.update(uri, values, null, null);
			} else {
				 throw new NullPointerException("downloadUri is null");
//				GlobalUtil.shortToast(mContext, R.string.downlod_error_msg);
//				return;
			}
		}
	}

	private void sendLog(String pckName, String action) {
		LogHandler lh = new LogHandler(mContext);
		lh.setParams(action, pckName);
		lh.onRequest(new RequestListener() {
			
			@Override
			public void onError(Object error) {
				
			}
			
			@Override
			public void onCallBack(Object data) {
				
			}
		}, false);
	}
	
	private Uri insertDownloadUri(ContentResolver contentResolver,
			String downloadUrl, int appId, String title, String packageName) {
		ContentValues values = new ContentValues();
		values.put(Downloads.COLUMN_MIME_TYPE, GlobalConstants.MIMETYPE_APK);
		values.put(Downloads.COLUMN_TITLE, title);
		values.put(Downloads.COLUMN_APP_ID, appId);
		values.put(Downloads.COLUMN_URI, downloadUrl);
		values.put(Downloads.COLUMN_NO_INTEGRITY, true);
		values.put(Downloads.COLUMN_VISIBILITY,
				Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
		values.put(Downloads.COLUMN_NOTIFICATION_PACKAGE,
				GlobalConstants.PACKAGE_NAME);
		values.put(Downloads.COLUMN_NOTIFICATION_CLASS,
				DownloadReceiver.class.getName());
		values.put(Downloads.COLUMN_NOTIFICATION_EXTRAS, packageName);
		if (GlobalUtil.isSDCardMounted()) {
			values.put(Downloads.COLUMN_DESTINATION,
					Downloads.DESTINATION_EXTERNAL);
		} else {
			values.put(Downloads.COLUMN_DESTINATION,
					Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE);
		}
		// values.put(Downloads.COLUMN_DOWNLOAD_TYPE, downloadType);
		Uri uri = contentResolver.insert(Downloads.CONTENT_URI, values);
		return uri;
	}

	public void trimDatabase() {
		_trimDatabase();
		removeSpuriousFiles();
	}

	/**
	 * Drops old rows from the database to prevent it from growing too large
	 */
	private void _trimDatabase() {
		Cursor cursor = mContext.getContentResolver().query(
				Downloads.CONTENT_URI, new String[] { Downloads._ID },
				Downloads.COLUMN_STATUS + " >= '200'", null,
				Downloads.COLUMN_LAST_MODIFICATION);
		if (cursor == null) {
			// This isn't good - if we can't do basic queries in our database,
			// nothing's gonna work
			Log.e(Constants.TAG, "null cursor in trimDatabase");
			return;
		}
		if (cursor.moveToFirst()) {
			int numDelete = cursor.getCount() - Constants.MAX_DOWNLOADS;
			int columnId = cursor.getColumnIndexOrThrow(Downloads._ID);
			while (numDelete > 0) {
				mContext.getContentResolver().delete(
						ContentUris.withAppendedId(Downloads.CONTENT_URI,
								cursor.getLong(columnId)), null, null);
				if (!cursor.moveToNext()) {
					break;
				}
				numDelete--;
			}
		}
		cursor.close();
	}

	/**
	 * Removes files that may have been left behind in the cache directory
	 */
	private void removeSpuriousFiles() {
		File[] files = Environment.getDownloadCacheDirectory().listFiles();
		if (files == null) {
			// The cache folder doesn't appear to exist (this is likely the case
			// when running the simulator).
			return;
		}
		HashSet<String> fileSet = new HashSet<String>();
		for (int i = 0; i < files.length; i++) {
			if (files[i].getName().equals(Constants.KNOWN_SPURIOUS_FILENAME)) {
				continue;
			}
			if (files[i].getName().equalsIgnoreCase(
					Constants.RECOVERY_DIRECTORY)) {
				continue;
			}
			fileSet.add(files[i].getPath());
		}

		Cursor cursor = mContext.getContentResolver().query(
				Downloads.CONTENT_URI, new String[] { Downloads._DATA }, null,
				null, null);
		if (cursor != null) {
			if (cursor.moveToFirst()) {
				do {
					fileSet.remove(cursor.getString(0));
				} while (cursor.moveToNext());
			}
			cursor.close();
		}
		Iterator<String> iterator = fileSet.iterator();
		while (iterator.hasNext()) {
			String filename = iterator.next();
			if (Constants.LOGV) {
				Log.v(Constants.TAG, "deleting spurious file " + filename);
			}
			new File(filename).delete();
		}
	}
}
